package io.youngledo.usb;

import io.youngledo.usb.security.CredentialManager;
import io.youngledo.usb.storage.StorageConfig;
import io.youngledo.usb.storage.StorageType;
import javafx.geometry.Insets;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;

import java.util.List;

public class ConnectionDialog extends Dialog<ConnectionResult> {

    private ComboBox<StorageType> storageTypeComboBox;
    private TextField endpointField;
    private TextField accessKeyField;
    private PasswordField secretKeyField;
    private CheckBox useSSLCheckBox;
    private TextField regionField;
    private TextField displayNameField; // 连接显示名称

    // 保存凭据选项
    private CheckBox saveCredentialsCheckBox;

    private final I18nManager i18n;
    private final ConfigManager configManager;
    private final CredentialManager credentialManager;

    // 存储类型变化监听器
    private javafx.beans.value.ChangeListener<StorageType> storageTypeChangeListener;

    // 标记是否已经自动加载了凭据
    private boolean credentialsAutoLoaded = false;

    public ConnectionDialog() {
        this(null); // 调用编辑构造函数，传入null表示新建
    }

    // 编辑连接的构造函数
    public ConnectionDialog(ConfigManager.SavedConnection editingConnection) {
        i18n = I18nManager.getInstance();
        configManager = new ConfigManager();
        credentialManager = CredentialManager.getInstance();

        setTitle(editingConnection == null ?
            i18n.getString("connection.title") :
            "编辑连接 - " + editingConnection.name);
        setHeaderText(null);

        // 应用扁平化样式
        io.youngledo.usb.util.DialogUtils.applyFlatStyle(this);

        // 创建按钮类型
        String buttonText = editingConnection == null ?
            i18n.getString("connection.connect") : "保存";
        ButtonType connectButtonType = new ButtonType(buttonText, ButtonBar.ButtonData.OK_DONE);
        getDialogPane().getButtonTypes().addAll(connectButtonType, ButtonType.CANCEL);

        // 创建输入控件
        createInputControls();

        // 创建布局
        GridPane grid = createLayout();
        getDialogPane().setContent(grid);

        // 设置对话框尺寸
        getDialogPane().setPrefWidth(500);
        getDialogPane().setMinWidth(450);

        // 如果是编辑模式，填充现有连接数据
        if (editingConnection != null) {
            loadConnectionForEditing(editingConnection);
        } else {
            // 初始化字段状态（不填充默认值）
            adjustFieldStatesForStorageType(StorageType.MINIO);
        }

        // 设置结果转换器
        setResultConverter(dialogButton -> {
            if (dialogButton == connectButtonType) {
                StorageConfig config = new StorageConfig(
                    storageTypeComboBox.getValue(),
                    endpointField.getText().trim(),
                    accessKeyField.getText().trim(),
                    secretKeyField.getText().trim(),
                    regionField.getText().trim(),
                    useSSLCheckBox.isSelected(),
                    null // bucketName can be null for now
                );

                // 获取显示名称
                String displayName = displayNameField.getText().trim();

                // 如果选择了保存凭据
                if (saveCredentialsCheckBox.isSelected() && !displayName.isEmpty()) {
                    credentialManager.saveCredentials(
                        displayName,
                        config.endpoint(),
                        config.accessKey(),
                        config.secretKey(),
                        config.region()
                    );
                }

                // 如果是编辑模式
                if (editingConnection != null) {
                    // 检查名称唯一性（排除当前编辑的连接）
                    if (!displayName.equals(editingConnection.name) &&
                        !checkConnectionNameUniqueness(displayName)) {
                        return null; // 阻止对话框关闭，让用户修改名称
                    }
                    // 删除旧连接，保存新连接
                    configManager.deleteConnection(editingConnection.name);
                    configManager.saveConnection(config, displayName);
                } else {
                    // 新建连接模式
                    if (!displayName.isEmpty()) {
                        if (!checkConnectionNameUniqueness(displayName)) {
                            return null; // 阻止对话框关闭，让用户修改名称
                        }
                        configManager.saveConnection(config, displayName);
                    }
                }

                return new ConnectionResult(config, displayName.isEmpty() ? null : displayName);
            }
            return null;
        });

        // 启用/禁用连接按钮
        Button connectButton = (Button) getDialogPane().lookupButton(connectButtonType);

        // 所有模式都需要验证必要字段
        // 创建自定义的绑定来检查密钥字段，考虑自动加载的情况
        javafx.beans.binding.BooleanBinding secretKeyValidBinding =
            javafx.beans.binding.Bindings.createBooleanBinding(
                () -> credentialsAutoLoaded || !secretKeyField.getText().trim().isEmpty(),
                secretKeyField.textProperty()
            );

        connectButton.disableProperty().bind(
            storageTypeComboBox.valueProperty().isNull()
                .or(endpointField.textProperty().isEmpty())
                .or(accessKeyField.textProperty().isEmpty())
                .or(secretKeyValidBinding.not())
        );

        // 默认焦点
        endpointField.requestFocus();
    }

    private void createInputControls() {
        // 存储类型选择器
        storageTypeComboBox = new ComboBox<>();
        storageTypeComboBox.getItems().addAll(StorageType.values());
        storageTypeComboBox.setValue(StorageType.MINIO);

        // 创建并添加存储类型变化监听器
        storageTypeChangeListener = (obs, oldVal, newVal) -> {
            // 只调整字段状态和提示语，不填充默认值
            adjustFieldStatesForStorageType(newVal);
        };
        storageTypeComboBox.valueProperty().addListener(storageTypeChangeListener);

        endpointField = new TextField();
        endpointField.setPromptText(i18n.getString("placeholder.endpoint"));

        // 添加端点变化监听器，用于自动解析区域
        endpointField.textProperty().addListener((obs, oldVal, newVal) -> {
            autoParseRegionFromEndpoint(newVal);
        });

        accessKeyField = new TextField();
        accessKeyField.setPromptText(i18n.getString("placeholder.accessKey"));

        secretKeyField = new PasswordField();
        secretKeyField.setPromptText(i18n.getString("placeholder.secretKey"));

        useSSLCheckBox = new CheckBox(i18n.getString("connection.useSSL"));

        regionField = new TextField();
        regionField.setPromptText(i18n.getString("placeholder.region"));

        // 连接显示名称
        displayNameField = new TextField();
        displayNameField.setPromptText("连接名称（可选，填写则自动保存连接）");

        // 保存凭据复选框
        saveCredentialsCheckBox = new CheckBox("保存凭据（加密存储）");
        saveCredentialsCheckBox.setSelected(true);
        saveCredentialsCheckBox.setTooltip(new Tooltip("选中此项将使用AES-256加密安全保存您的AccessKey和SecretKey"));
    }


    private GridPane createLayout() {
        GridPane grid = new GridPane();
        grid.setHgap(15);
        grid.setVgap(12);
        grid.setPadding(new Insets(20, 20, 15, 20));

        int row = 0;


        // 连接显示名称
        grid.add(new Label("连接名称:"), 0, row);
        grid.add(displayNameField, 1, row++);

        // 添加控件到网格
        grid.add(new Label(i18n.getString("connection.type")), 0, row);
        grid.add(storageTypeComboBox, 1, row++);

        grid.add(new Label(i18n.getString("connection.endpoint")), 0, row);
        grid.add(endpointField, 1, row++);

        grid.add(new Label(i18n.getString("connection.accessKey")), 0, row);
        grid.add(accessKeyField, 1, row++);

        grid.add(new Label(i18n.getString("connection.secretKey")), 0, row);
        grid.add(secretKeyField, 1, row++);

        grid.add(new Label(i18n.getString("connection.region")), 0, row);
        grid.add(regionField, 1, row++);

        grid.add(useSSLCheckBox, 1, row++);

        // 保存凭据选项
        grid.add(saveCredentialsCheckBox, 1, row++);


        // 设置列宽和首选宽度
        GridPane.setHgrow(displayNameField, Priority.ALWAYS);
        GridPane.setHgrow(storageTypeComboBox, Priority.ALWAYS);
        GridPane.setHgrow(endpointField, Priority.ALWAYS);
        GridPane.setHgrow(accessKeyField, Priority.ALWAYS);
        GridPane.setHgrow(secretKeyField, Priority.ALWAYS);
        GridPane.setHgrow(regionField, Priority.ALWAYS);

        // 设置输入框的首选宽度
        displayNameField.setPrefWidth(350);
        storageTypeComboBox.setPrefWidth(350);
        storageTypeComboBox.setMaxWidth(Double.MAX_VALUE); // 确保ComboBox能够扩展到最大宽度
        endpointField.setPrefWidth(350);
        accessKeyField.setPrefWidth(350);
        secretKeyField.setPrefWidth(350);
        regionField.setPrefWidth(350);

        return grid;
    }


    /// 只调整字段的启用/禁用状态和提示语，不修改字段值
    ///
    private void adjustFieldStatesForStorageType(StorageType type) {
        if (type == null) return;

        switch (type) {
            case MINIO -> {
                // 启用所有字段
                endpointField.setDisable(false);
                regionField.setDisable(true); // MinIO区域可选，隐藏输入
                regionField.setText(""); // 清空区域
                useSSLCheckBox.setDisable(false);
                useSSLCheckBox.setSelected(false);

                // 设置提示语
                endpointField.setPromptText("localhost:9000");
                accessKeyField.setPromptText("AccessKey");
                secretKeyField.setPromptText("SecretKey");
                regionField.setPromptText("MinIO无需区域配置");
            }
            case ALIYUN_OSS -> {
                // OSS 总是使用 HTTPS
                useSSLCheckBox.setDisable(true);
                useSSLCheckBox.setSelected(true);
                regionField.setDisable(true); // 从端点自动解析
                endpointField.setDisable(false);

                // 设置提示语
                endpointField.setPromptText("oss-cn-hangzhou.aliyuncs.com");
                accessKeyField.setPromptText("AccessKey ID");
                secretKeyField.setPromptText("AccessKey Secret");
                regionField.setPromptText("将从端点自动解析");
            }
            case TENCENT_COS -> {
                // COS 总是使用 HTTPS
                useSSLCheckBox.setDisable(true);
                useSSLCheckBox.setSelected(true);
                regionField.setDisable(true); // 与端点同步
                endpointField.setDisable(false);

                // 设置提示语
                endpointField.setPromptText("ap-beijing");
                accessKeyField.setPromptText("SecretId");
                secretKeyField.setPromptText("SecretKey");
                regionField.setPromptText("与端点同步");
            }
            case HUAWEI_OBS -> {
                // OBS 总是使用 HTTPS
                useSSLCheckBox.setDisable(true);
                useSSLCheckBox.setSelected(true);
                regionField.setDisable(true); // 从端点自动解析
                endpointField.setDisable(false);

                // 设置提示语
                endpointField.setPromptText("obs.cn-north-4.myhuaweicloud.com");
                accessKeyField.setPromptText("Access Key");
                secretKeyField.setPromptText("Secret Key");
                regionField.setPromptText("将从端点自动解析");
            }
            default -> {
                // 其他存储服务保持区域字段可编辑
                regionField.setDisable(false);
                regionField.setPromptText("区域 (可选)");
            }
        }
    }

    /// 从端点自动解析区域
    ///
    private void autoParseRegionFromEndpoint(String endpoint) {
        if (endpoint == null || endpoint.trim().isEmpty()) {
            return;
        }

        StorageType currentType = storageTypeComboBox.getValue();
        if (currentType == null) return;

        String parsedRegion = "";

        switch (currentType) {
            case ALIYUN_OSS -> {
                // 从 oss-cn-hangzhou.aliyuncs.com 提取 oss-cn-hangzhou
                if (endpoint.contains(".aliyuncs.com")) {
                    parsedRegion = endpoint.replace(".aliyuncs.com", "");
                }
            }
            case HUAWEI_OBS -> {
                // 从 obs.cn-north-4.myhuaweicloud.com 提取 cn-north-4
                if (endpoint.startsWith("obs.") && endpoint.contains(".myhuaweicloud.com")) {
                    String temp = endpoint.replace("obs.", "").replace(".myhuaweicloud.com", "");
                    parsedRegion = temp;
                }
            }
            case TENCENT_COS -> {
                // 腾讯云COS端点就是区域
                parsedRegion = endpoint.trim();
            }
            case MINIO -> {
                // MinIO不需要区域
                parsedRegion = "";
            }
        }

        regionField.setText(parsedRegion);
    }

    // 编辑模式下加载连接数据
    private void loadConnectionForEditing(ConfigManager.SavedConnection savedConnection) {
        // 临时移除存储类型监听器，避免覆盖我们要设置的值
        storageTypeComboBox.valueProperty().removeListener(storageTypeChangeListener);

        try {
            // 设置存储类型
            storageTypeComboBox.setValue(savedConnection.type);

            // 设置保存的连接值
            endpointField.setText(savedConnection.endpoint);
            accessKeyField.setText(savedConnection.accessKey);
            regionField.setText(savedConnection.region);
            useSSLCheckBox.setSelected(savedConnection.useSSL);

            // 尝试从凭据管理器加载加密的密钥
            CredentialManager.StoredCredential credential = credentialManager.loadCredentials(savedConnection.name);
            if (credential != null && credential.getSecretKey() != null && !credential.getSecretKey().isEmpty()) {
                // 如果找到加密保存的密钥，自动填充
                secretKeyField.setText(credential.getSecretKey());
                secretKeyField.setPromptText("已自动填充保存的密钥");
                credentialsAutoLoaded = true; // 标记为已自动加载
            } else {
                // 如果没有保存的密钥，需要重新输入
                secretKeyField.setText("");
                secretKeyField.setPromptText("请重新输入密钥");
                credentialsAutoLoaded = false;
            }

            // 设置连接名称
            displayNameField.setText(savedConnection.name);

            // 只调整字段的启用/禁用状态，不修改值
            adjustFieldStatesForStorageType(savedConnection.type);

            // 重新触发端点解析（编辑模式下需要重新解析）
            autoParseRegionFromEndpoint(savedConnection.endpoint);

        } finally {
            // 重新添加存储类型监听器
            storageTypeComboBox.valueProperty().addListener(storageTypeChangeListener);
        }
    }

    /// 检查连接名称唯一性
    ///
    private boolean checkConnectionNameUniqueness(String connectionName) {
        List<ConfigManager.SavedConnection> existingConnections = configManager.loadAllConnections();
        boolean nameExists = existingConnections.stream()
                .anyMatch(conn -> conn.name.equals(connectionName));

        if (nameExists) {
            // 显示确认对话框
            Alert confirmDialog = new Alert(Alert.AlertType.CONFIRMATION);
            confirmDialog.setTitle("连接名称重复");
            confirmDialog.setHeaderText("连接名称已存在");
            confirmDialog.setContentText("连接名称 \"" + connectionName + "\" 已存在。\n\n" +
                    "点击\"确定\"将覆盖现有连接，点击\"取消\"可修改连接名称。");

            return confirmDialog.showAndWait()
                    .map(response -> response == ButtonType.OK)
                    .orElse(false);
        }

        return true; // 名称唯一，可以保存
    }

    /// 根据endpoint推断存储类型
    ///
    private StorageType detectStorageTypeFromEndpoint(String endpoint) {
        if (endpoint.contains("aliyuncs.com")) {
            return StorageType.ALIYUN_OSS;
        } else if (endpoint.contains("cos.")) {
            return StorageType.TENCENT_COS;
        } else if (endpoint.contains("myhuaweicloud.com")) {
            return StorageType.HUAWEI_OBS;
        } else if (endpoint.contains("volcengineapi.com")) {
            return StorageType.VOLC_ENGINE_TOS;
        } else if (endpoint.contains("bcebos.com")) {
            return StorageType.BAIDU_BOS;
        } else if (!endpoint.contains(".")) {
            // 可能是MinIO的本地地址
            return StorageType.MINIO;
        }
        return null;
    }

    /// 显示信息提示
    ///
    private void showInfoAlert(String title, String message) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle(title);
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }

    /// 显示错误提示
    ///
    private void showErrorAlert(String title, String message) {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle(title);
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }

}